import json
import uuid
import time
from fastapi import APIRouter, BackgroundTasks
from appConfig import appConfig
from assistoollib.SyncTool.mailExchange import mailExchange
from assistoollib.Updater.dataService import DataService
from assistoollib.DataSource.mysql import MySqlDataSource
from sqlmodel import Session, select
from sqlalchemy import func
from assistoollib.Entity.Opportunity import Opportunity
from datetime import datetime, timedelta

import threading
import asyncio

router = APIRouter(prefix="/opp", tags=["商机同步接口"])

# 任务状态跟踪字典
_task_status = {}
# 任务过期时间（秒）
TASK_EXPIRATION_SECONDS = 3600  # 1小时

def run_task_in_thread(func: callable, task_id: str):

    # 启动新线程执行任务
    def thread_target():
        asyncio.run(func(task_id))
    
    thread = threading.Thread(target=thread_target)
    thread.start()
    return thread


async def _random_push(task_id: str):
    # 初始化任务状态
    _task_status[task_id] = {
        "status": "running",
        "progress": 0,
        "total": 0,
        "processed": 0,
        "message": "随机推送任务开始执行",
        "start_time": time.time()
    }

    # 连接mysql
    ds = MySqlDataSource(
        ipAddress = appConfig().mysql_config.ipAddress,
        database = appConfig().mysql_config.database,
        username = appConfig().mysql_config.username,
        password = appConfig().mysql_config.password,
        port = appConfig().mysql_config.port,
        echo = appConfig().mysql_config.echo,
    )

    engine = ds.createEngine()
    with Session(engine) as session:
        # 随机获取10条lastCrawledTime超过24小时的数据
        twenty_four_hours_ago = datetime.now() - timedelta(hours=24)
        statement = select(Opportunity).where(
            Opportunity.lastCrawledTime < twenty_four_hours_ago,
            Opportunity.oppCode.like("SH2025%"),
            Opportunity.status.not_in(["已关闭", "已签约"])
        ).order_by(func.rand()).limit(100)
        result = session.exec(statement).all()
        
        total_count = len(result)
        _task_status[task_id]["total"] = total_count
        _task_status[task_id]["message"] = f"发现 {total_count} 条数据待处理"
        
        if total_count == 0:
            _task_status[task_id]["status"] = "completed"
            _task_status[task_id]["message"] = "本次没有需要同步的数据"
            _task_status[task_id]["end_time"] = time.time()
            print("本次没有需要同步的数据")
            return

        oppList = []
        print(f"共有{total_count}条数据")
        
        for i, opp in enumerate(result, 1):
            oppList.append({
                "oppCode": opp.opportunityNumber,
                "url": opp.opportunityUrl
            })
            print(f"{i}/{total_count} - ({opp.opportunityNumber}) {opp.opportunityName}")

            # 更新进度
            progress = int((i / total_count) * 100)
            _task_status[task_id]["progress"] = progress
            _task_status[task_id]["processed"] = i
            _task_status[task_id]["message"] = f"已处理 {i}/{total_count} 条数据"

        # print(json.dumps(oppList, indent=4, ensure_ascii=False))

        # 发送邮件
        mailex = mailExchange(appConfig().mailbox_config)
        mailex.pushData(
            title=f"{datetime.now().strftime('%Y%m%d%H%M%S')}_DataForUpdate", 
            data=json.dumps(oppList, indent=4, ensure_ascii=False)
        )
        
        # 任务完成
        _task_status[task_id]["status"] = "completed"
        _task_status[task_id]["progress"] = 100
        _task_status[task_id]["message"] = f"任务完成，共处理 {total_count} 条数据"
        _task_status[task_id]["end_time"] = time.time()
    return oppList


async def _process_sync(task_id: str):
    # 初始化任务状态
    _task_status[task_id] = {
        "status": "running",
        "progress": 0,
        "total": 0,
        "processed": 0,
        "message": "任务开始执行",
        "start_time": time.time()
    }

    mailex = mailExchange(appConfig().mailbox_config)
    total_processed = 0
    all_opps = []

    # 首先收集所有数据以获取总数
    for msg in mailex.syncData(filename_pattern = r'^\d{14}_DataUpdated.bin$'):
        opps = json.loads(msg)
        all_opps.extend(opps)

    total_count = len(all_opps)
    _task_status[task_id]["total"] = total_count
    _task_status[task_id]["message"] = f"发现 {total_count} 条数据待处理"

    # 处理数据
    count = 0
    for item in all_opps:
        count += 1
        print(f"{count}/{total_count} - {item['oppCode']} - {item['opp_data']['商机名称']}")
        ds = DataService(
            sqliteConfig = None,
            mysqlConfig = appConfig().mysql_config
        )
        ds.saveCrawledDataMysql(item)
        total_processed += 1

        # 更新进度
        progress = int((count / total_count) * 100)
        _task_status[task_id]["progress"] = progress
        _task_status[task_id]["processed"] = total_processed
        _task_status[task_id]["message"] = f"已处理 {count}/{total_count} 条数据"

    # 任务完成
    _task_status[task_id]["status"] = "completed"
    _task_status[task_id]["progress"] = 100
    _task_status[task_id]["message"] = f"任务完成，共处理 {total_processed} 条数据"
    _task_status[task_id]["end_time"] = time.time()

    return total_processed

# 清理过期任务
def _cleanup_expired_tasks():
    current_time = time.time()
    expired_task_ids = []

    for task_id, status in _task_status.items():
        # 检查任务是否已完成且超过过期时间
        if status["status"] == "completed" and \
           "end_time" in status and \
           (current_time - status["end_time"]) > TASK_EXPIRATION_SECONDS:
            expired_task_ids.append(task_id)

    # 删除过期任务
    for task_id in expired_task_ids:
        del _task_status[task_id]
        print(f"已清理过期任务: {task_id}")

@router.post("/sync")
async def sync_opp(background_tasks: BackgroundTasks):
    # 清理过期任务
    _cleanup_expired_tasks()

    # 生成唯一任务ID
    task_id = str(uuid.uuid4())
    # 添加到后台任务
    background_tasks.add_task(run_task_in_thread, _process_sync, task_id)

    # 返回任务ID，供查询使用
    return {
        "success": True,
        "message": "同步操作已开始，将在后台执行",
        "task_id": task_id
    }


@router.post("/rdpush")
async def random_push_opp(background_tasks: BackgroundTasks):
    # 清理过期任务
    _cleanup_expired_tasks()
    # 生成唯一任务ID
    task_id = str(uuid.uuid4())
    # 添加到后台任务 - 修复参数传递问题
    background_tasks.add_task(run_task_in_thread, _random_push, task_id)

    # 返回任务ID，供查询使用
    return {
        "success": True,
        "message": "随机推送操作已开始，将在后台执行",
        "task_id": task_id
    }



@router.get("/sync/status/{task_id}")
async def get_sync_status(task_id: str):
    # 查询任务状态
    if task_id not in _task_status:
        return {
            "success": False,
            "message": "任务ID不存在"
        }
    return {
        "success": True,
        "task_id": task_id,
        "status": _task_status[task_id]
    }

@router.delete("/sync/status/{task_id}")
async def delete_task_status(task_id: str):
    # 手动删除指定任务状态
    if task_id not in _task_status:
        return {
            "success": False,
            "message": "任务ID不存在"
        }
    del _task_status[task_id]
    return {
        "success": True,
        "message": f"已删除任务状态: {task_id}"
    }

@router.get("/sync/tasks")
async def list_tasks():
    # 清理过期任务
    _cleanup_expired_tasks()

    # 返回所有非过期任务的ID和状态
    return {
        "success": True,
        "tasks": {
            task_id: {"status": status["status"], "progress": status["progress"], "message": status["message"]}
            for task_id, status in _task_status.items()
        }
    }